package com.syspeak.modules.spring.web.servlet.view.json;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.json.JSONException;
import org.codehaus.jackson.map.SerializerFactory;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.Assert;
import org.springframework.web.servlet.view.json.MappingJacksonJsonView;

import com.syspeak.modules.utils.json.JsonLibObjectMapper;

public class MappingJsonLibJsonView extends MappingJacksonJsonView {

	private JsonLibObjectMapper objectMapper = new JsonLibObjectMapper();

	/**
	 * Sets the {@code ObjectMapper} for this view. If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper}
	 * is used.
	 *
	 * <p>Setting a custom-configured {@code ObjectMapper} is one way to take further control of the JSON serialization
	 * process. For example, an extended {@link SerializerFactory} can be configured that provides custom serializers for
	 * specific types. The other option for refining the serialization process is to use Jackson's provided annotations on
	 * the types to be serialized, in which case a custom-configured ObjectMapper is unnecessary.
	 */
	public void setObjectMapper(JsonLibObjectMapper objectMapper) {
		Assert.notNull(objectMapper, "'objectMapper' must not be null");
		this.objectMapper = objectMapper;
	}

	@Override
	protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Object value = filterModel(model);
		boolean writeGzip = false;
		try {
			objectMapper.writeValueToResponse(value, response, writeGzip);
		} catch (JSONException e) {
			e.printStackTrace();
			throw new HttpMessageNotWritableException(e.getMessage(), e.getCause());
		}
	}

}
